﻿#ifndef CVT_XVL_H
#define CVT_XVL_H

#include "structdata.h"
#include "XVBase.h"
#include "RobotBase.h"
#include "robotdata.h"

using namespace XVL;

namespace xvs {

//Point2DInt
inline void toXVPoint2DInt(xvs::Point2DInt& inPoint,XVL::XVPoint2DInt& outPoint)
{
    outPoint.x = inPoint.X()->Value();
    outPoint.y = inPoint.Y()->Value();
}
inline void fromXVPoint2DInt(XVL::XVPoint2DInt& inPoint,xvs::Point2DInt& outPoint)
{
    Integer ix(inPoint.x);
    Integer iy(inPoint.y);
    outPoint.SetX(&ix);
    outPoint.SetY(&iy);
}

//Point2D
inline void toXVPoint2D(xvs::Point2D& inPoint,XVL::XVPoint2D& outPoint)
{
    outPoint.x = inPoint.X()->Value();
    outPoint.y = inPoint.Y()->Value();
}
inline void fromXVPoint2D(XVL::XVPoint2D& inPoint,xvs::Point2D& outPoint)
{
    Real rx(inPoint.x);
    Real ry(inPoint.y);
    outPoint.SetX(&rx);
    outPoint.SetY(&ry);
}

//Point3D
inline void toXVPoint3D(xvs::Point3D& inPoint,XVL::XVPoint3D& outPoint)
{
    outPoint.x = inPoint.X()->Value();
    outPoint.y = inPoint.Y()->Value();
    outPoint.z = inPoint.Z()->Value();
}
inline void fromXVPoint3D(XVL::XVPoint3D& inPoint,xvs::Point3D& outPoint)
{
    Real rx(inPoint.x);
    Real ry(inPoint.y);
    Real rz(inPoint.z);
    outPoint.SetX(&rx);
    outPoint.SetY(&ry);
    outPoint.SetZ(&rz);
}

//Circle2D
inline void toXVCircle2D(xvs::Circle2D& inCircle,XVL::XVCircle2D& outCircle)
{
    toXVPoint2D(*inCircle.Center(),outCircle.center);
    outCircle.radius = inCircle.Radius()->Value();
}
inline void fromXVCircle2D(XVL::XVCircle2D& inCircle,xvs::Circle2D& outCircle)
{
    fromXVPoint2D(inCircle.center,*outCircle.Center());
    Real _radius(inCircle.radius);
    outCircle.SetRadius(&_radius);
}

//CircleFittingField
inline void toXVCircleFittingField(xvs::CircleFittingField& inCircleFit,XVCircleFittingField& outCircleFit)
{
    toXVCircle2D(*inCircleFit.Axis(),outCircleFit.axis);
    outCircleFit.width = inCircleFit.Width()->Value();
}
inline void fromXVCircleFittingField(XVCircleFittingField& inCircleFit,xvs::CircleFittingField& outCircleFit)
{
    fromXVCircle2D(inCircleFit.axis,*outCircleFit.Axis());
    Real _width(inCircleFit.width);
    outCircleFit.SetWidth(&_width);
}

//Arc2D
inline void toXVArc2D(xvs::Arc2D& inArc,XVArc2D& outArc)
{
    toXVPoint2D(*inArc.Center(),outArc.center);
    outArc.radius = inArc.Radius()->Value();
    outArc.startAngle = inArc.StartAngle()->Value();
    outArc.sweepAngle = inArc.SweepAngle()->Value();
}
inline void fromXVArc2D(XVArc2D& inArc,xvs::Arc2D& outArc)
{
    fromXVPoint2D(inArc.center,*outArc.Center());
    Real _radius(inArc.radius);
    Real _startAngle(inArc.startAngle);
    Real _sweepAngle(inArc.sweepAngle);
    outArc.SetRadius(&_radius);
    outArc.SetRadius(&_startAngle);
    outArc.SetRadius(&_sweepAngle);
}

//ArcFittingField 圆弧域
inline void toXVArcFittingField(xvs::ArcFittingField& inArcFit,XVArcFittingField& outArcFit)
{
    toXVArc2D(*inArcFit.Axis(),outArcFit.axis);
    outArcFit.width = inArcFit.Width()->Value();
}
inline void fromXVArcFittingField(XVArcFittingField& inArcFit,xvs::ArcFittingField& outArcFit)
{
    fromXVArc2D(inArcFit.axis,*outArcFit.Axis());
    Real _width(inArcFit.width);
    outArcFit.SetWidth(&_width);
}

//Rectangle2D
inline void toXVRectangle2D(xvs::Rectangle2D& inRect,XVRectangle2D& outRect)
{
    toXVPoint2D(*inRect.Origin(),outRect.origin);
    outRect.angle = inRect.Angle()->Value();
    outRect.width = inRect.Width()->Value();
    outRect.height = inRect.Height()->Value();
}
inline void fromXVRectangle2D(XVRectangle2D& inRect,xvs::Rectangle2D& outRect)
{
    fromXVPoint2D(inRect.origin,*outRect.Origin());
    Real _angle(inRect.angle);
    Real _width(inRect.width);
    Real _height(inRect.height);
    outRect.SetAngle(&_angle);
    outRect.SetWidth(&_width);
    outRect.SetHeight(&_height);
}

//Rectangle2DInt
inline void toXVRectangle2DInt(xvs::Rectangle2DInt& inRect,XVRectangle2DInt& outRect)
{
    toXVPoint2DInt(*inRect.Origin(),outRect.origin);
    outRect.angle = inRect.Angle()->Value();
    outRect.width = inRect.Width()->Value();
    outRect.height = inRect.Height()->Value();
}
inline void fromXVRectangle2DInt(XVRectangle2DInt& inRect,xvs::Rectangle2DInt& outRect)
{
    fromXVPoint2DInt(inRect.origin,*outRect.Origin());
    Real _angle(inRect.angle);
    Integer _width(inRect.width);
    Integer _height(inRect.height);
    outRect.SetAngle(&_angle);
    outRect.SetWidth(&_width);
    outRect.SetHeight(&_height);
}

//Box2D
inline void toXVBox2D(xvs::Box2D& inBox,XVBox& outBox)
{
    outBox.origin.x = inBox.X()->Value();
    outBox.origin.y = inBox.Y()->Value();
    outBox.width = inBox.Width()->Value();
    outBox.height = inBox.Height()->Value();
}
inline void fromXVBox2D(XVBox& inBox,xvs::Box2D& outBox)
{
    Real _x(inBox.origin.x);
    Real _y(inBox.origin.y);
    Real _width(inBox.width);
    Real _height(inBox.height);
    outBox.SetX(&_x);
    outBox.SetY(&_y);
    outBox.SetWidth(&_width);
    outBox.SetHeight(&_height);
}

//Edge1D
inline void toXVEdge1D(xvs::Edge1D& inEdge,XVEdge1D& outEdge)
{
    toXVPoint2D(*inEdge.Point(),outEdge.point);
    outEdge.magnitude = inEdge.Magnitude()->Value();
    outEdge.transition = (XVEdgeTransitionType)inEdge.Transition()->Key();
}
inline void fromXVEdge1D(XVEdge1D& inEdge,xvs::Edge1D& outEdge)
{
    fromXVPoint2D(inEdge.point,*outEdge.Point());
    Real _magnitude(inEdge.magnitude);
    EdgeTransitionType _transition;
    _transition.SetKey(inEdge.transition);
    outEdge.SetMagnitude(&_magnitude);
    outEdge.SetTransition(&_transition);
}

//Gap1D
inline void toXVGap1D(xvs::Gap1D& inGap1D,XVGap1D& outGap1D)
{
    toXVPoint2D(*inGap1D.Point1(),outGap1D.point1);
    toXVPoint2D(*inGap1D.Point2(),outGap1D.point2);
    outGap1D.width = inGap1D.Width()->Value();
}
inline void fromXVGap1D(XVGap1D& inGap1D,xvs::Gap1D& outGap1D)
{
    fromXVPoint2D(inGap1D.point1,*outGap1D.Point1());
    fromXVPoint2D(inGap1D.point2,*outGap1D.Point2());

    Real _width(inGap1D.width);
    outGap1D.SetWidth(&_width);
}

//Line2D
inline void toXVLine2D(xvs::Line2D& inLine,XVLine2D& outLine)
{
    outLine.a = inLine.A()->Value();
    outLine.b = inLine.B()->Value();
    outLine.c = inLine.C()->Value();
}
inline void fromXVLine2D(XVLine2D& inLine,xvs::Line2D& outLine)
{
    Real _a(inLine.a);
    Real _b(inLine.b);
    Real _c(inLine.c);
    outLine.SetA(&_a);
    outLine.SetB(&_b);
    outLine.SetC(&_c);
}

//PointRun
inline void toXVPointRun(xvs::PointRun& inPointRun,XVPointRun& outPointRun)
{
    outPointRun.x = inPointRun.X()->Value();
    outPointRun.y = inPointRun.Y()->Value();
    outPointRun.length = inPointRun.Length()->Value();
}
inline void fromXVPointRun(XVPointRun& inPointRun,xvs::PointRun& outPointRun)
{
    Integer _x(inPointRun.x);
    Integer _y(inPointRun.y);
    Integer _length(inPointRun.length);
    outPointRun.SetX(&_x);
    outPointRun.SetY(&_y);
    outPointRun.SetLength(&_length);
}

//Region
inline void toXVRegion(xvs::Region& inRegion,XVRegion& outRegion)
{
    if (inRegion.IsNull().Value())
    {
        outRegion.optional = NUL;
        outRegion.frameHeight = 0;
        outRegion.frameWidth = 0;
        outRegion.arrayPointRun.clear();
        return;
    }

    outRegion.optional = ENABLE;
    outRegion.frameHeight = inRegion.FrameHeight()->Value();
    outRegion.frameWidth = inRegion.FrameWidth()->Value();

    outRegion.arrayPointRun.clear();
    for (int i = 0; i< inRegion.ArrayPointRun()->Count(); i++)
    {
        PointRun pointrun = inRegion.ArrayPointRun()->At<PointRun>(i);
        XVPointRun xvPointRun;
        toXVPointRun(pointrun,xvPointRun);
        outRegion.arrayPointRun.push_back(xvPointRun);
    }
}
inline void fromXVRegion(XVRegion& inRegion,xvs::Region& outRegion)
{
    if (inRegion.optional == NUL)
    {
        outRegion.Clear();
        return;
    }

    Integer _frameWidth(inRegion.frameWidth);
    Integer _frameHeight(inRegion.frameHeight);

    outRegion.SetFrameWidth(&_frameWidth);
    outRegion.SetFrameHeight(&_frameHeight);

    outRegion.ArrayPointRun()->Clear();
    for (int i = 0; i< inRegion.arrayPointRun.size(); i++)
    {
        XVPointRun xvPointRun = inRegion.arrayPointRun.at(i);
        PointRun pointrun;
        fromXVPointRun(xvPointRun,pointrun);
        outRegion.ArrayPointRun()->Push_Back<PointRun>(pointrun);
    }
}

//Path
inline void toXVPath(xvs::Path& inPath,XVPath& outPath)
{
    outPath.arrayPoint2D.clear();
    for (int i = 0; i< inPath.ArrayPoint()->Count(); i++)
    {
        Point2D point = inPath.ArrayPoint()->At<Point2D>(i);
        XVPoint2D xvPoint;
        toXVPoint2D(point,xvPoint);
        outPath.arrayPoint2D.push_back(xvPoint);
    }
}
inline void fromXVPath(XVPath& inPath,xvs::Path& outPath)
{
    outPath.ArrayPoint()->Clear();
    for (int i = 0; i< inPath.arrayPoint2D.size(); i++)
    {
        XVPoint2D xvPoint = inPath.arrayPoint2D.at(i);
        Point2D point;
        fromXVPoint2D(xvPoint,point);
        outPath.ArrayPoint()->Push_Back<Point2D>(point);
    }
}

//PathFittingField
inline void toXVPathFittingField(xvs::PathFittingField& inPathField,XVPathFittingField& outPathField)
{
    toXVPath(*inPathField.Axis(),outPathField.axis);
    outPathField.width = inPathField.Width()->Value();
}
inline void fromXVPathFittingField(XVPathFittingField& inPathField,xvs::PathFittingField& outPathField)
{
    fromXVPath(inPathField.axis,*outPathField.Axis());
    Real _width(inPathField.width);
    outPathField.SetWidth(&_width);
}

//Ridge1D
inline void toXVRidge1D(xvs::Ridge1D& inRidge,XVRidge1D& outRidge)
{
    toXVPoint2D(*inRidge.Point(),outRidge.point);
    outRidge.magnitude = inRidge.Magnitude()->Value();
    outRidge.polarity = (XVPolarityType)inRidge.Polarity()->Key();
}
inline void fromXVRidge1D(XVRidge1D& inRidge,xvs::Ridge1D& outRidge)
{
    fromXVPoint2D(inRidge.point,*outRidge.Point());
    Real _magnitude(inRidge.magnitude);
    PolarityType _polarity;
    _polarity.SetKey(inRidge.polarity);
    outRidge.SetMagnitude(&_magnitude);
    outRidge.SetPolarity(&_polarity);
}

//Stripe1D
inline void toXVStripe1D(xvs::Stripe1D& inStripe,XVStripe1D& outStripe)
{
    toXVPoint2D(*inStripe.Point1(),outStripe.point1);
    toXVPoint2D(*inStripe.Point2(),outStripe.point2);
    outStripe.width = inStripe.Width()->Value();
    outStripe.magnitude = inStripe.Magnitude()->Value();
    outStripe.polarity = (XVPolarityType)inStripe.Polarity()->Key();
}
inline void fromXVStripe1D(XVStripe1D& inStripe,xvs::Stripe1D& outStripe)
{
    fromXVPoint2D(inStripe.point1,*outStripe.Point1());
    fromXVPoint2D(inStripe.point2,*outStripe.Point2());

    Real _width(inStripe.width);
    outStripe.SetWidth(&_width);
    Real _magnitude(inStripe.magnitude);
    outStripe.SetMagnitude(&_magnitude);

    PolarityType _polarity;
    _polarity.SetKey(inStripe.polarity);
    outStripe.SetPolarity(&_polarity);
}

//Segment2D
inline void toXVSegment2D(xvs::Segment2D& inSegment2D,XVSegment2D& outSegment2D)
{
    toXVPoint2D(*inSegment2D.Point1(),outSegment2D.point1);
    toXVPoint2D(*inSegment2D.Point2(),outSegment2D.point2);
}
inline void fromXVSegment2D(XVSegment2D& inSegment2D,xvs::Segment2D& outSegment2D)
{
    fromXVPoint2D(inSegment2D.point1,*outSegment2D.Point1());
    fromXVPoint2D(inSegment2D.point2,*outSegment2D.Point2());
}

//SegmentFittingField
inline void toXVSegmentFittingField(xvs::SegmentFittingField& inSegmentField,XVSegmentFittingField& outSegmentField)
{
    toXVSegment2D(*inSegmentField.Axis(),outSegmentField.axis);
    outSegmentField.width = inSegmentField.Width()->Value();
}
inline void fromXVSegmentFittingField(XVSegmentFittingField& inSegmentField,xvs::SegmentFittingField& outSegmentField)
{
    fromXVSegment2D(inSegmentField.axis,*outSegmentField.Axis());
    Real _width(inSegmentField.width);
    outSegmentField.SetWidth(&_width);
}

//CoordinateSystem2D
inline void toXVCoordinateSystem2D(xvs::CoordinateSystem2D& inCoor,XVCoordinateSystem2D& outCoor)
{
    outCoor.optional = ENABLE;
    if (inCoor.IsNull().Value())
    {
        outCoor.optional = NUL;
        outCoor.origin.x = 0;
        outCoor.origin.y = 0;
        outCoor.angle = 0;
        outCoor.scale = 1;
        return;
    }

    toXVPoint2D(*inCoor.Origin(),outCoor.origin);
    outCoor.angle = inCoor.Angle()->Value();
    outCoor.scale = inCoor.Scale()->Value();
}
inline void fromXVCoordinateSystem2D(XVCoordinateSystem2D& inCoor,xvs::CoordinateSystem2D& outCoor)
{
    if (inCoor.optional == NUL)
    {
        outCoor.Clear();
        return;
    }

    fromXVPoint2D(inCoor.origin,*outCoor.Origin());
    Real _angle(inCoor.angle);
    Real _scale(inCoor.scale);
    outCoor.SetAngle(&_angle);
    outCoor.SetScale(&_scale);
}

//Object2D
inline void toXVObject2D(xvs::Object2D& inObject2D,XVObject2D& outObject2D)
{
    toXVRectangle2D(*inObject2D.Match(),outObject2D.match);
    toXVCoordinateSystem2D(*inObject2D.Alignment(),outObject2D.alignment);
    toXVPoint2D(*inObject2D.Point(),outObject2D.point);
    outObject2D.angle = inObject2D.Angle()->Value();
    outObject2D.scale = inObject2D.Scale()->Value();
    outObject2D.score = inObject2D.Score()->Value();
}
inline void fromXVObject2D(XVObject2D& inObject2D,xvs::Object2D& outObject2D)
{
    fromXVRectangle2D(inObject2D.match,*outObject2D.Match());
    fromXVCoordinateSystem2D(inObject2D.alignment,*outObject2D.Alignment());
    fromXVPoint2D(inObject2D.point,*outObject2D.Point());
    Real _angle(inObject2D.angle);
    Real _scale(inObject2D.scale);
    Real _score(inObject2D.score);
    outObject2D.SetAngle(&_angle);
    outObject2D.SetScale(&_scale);
    outObject2D.SetScore(&_score);
}

inline void toXVImage(xvs::Image& inImage,XVImage& outImage)
{
    if (outImage.data != nullptr)
    {
        free(outImage.data);
        outImage.data = nullptr;
    }

    outImage.width = inImage.Width()->Value();
    outImage.height = inImage.Height()->Value();
    outImage.type = (XVPlainType)inImage.Type()->Key();
    outImage.depth = inImage.Depth()->Value();

    int size = outImage.width * outImage.height * outImage.depth;

    outImage.data = (uchar*)malloc(size);
    memcpy(outImage.data,inImage.ConstBits(),size);
}

inline void toXVImage_Link(xvs::Image& inImage,XVImage& outImage)
{
    outImage.width = inImage.Width()->Value();
    outImage.height = inImage.Height()->Value();
    outImage.type = (XVPlainType)inImage.Type()->Key();
    outImage.depth = inImage.Depth()->Value();

    outImage.data = inImage.Bits();
}

inline void fromXVImage(XVImage& inImage,xvs::Image& outImage)
{
//    outImage = Image(inImage.width,inImage.height,(ImageData::PlainType)inImage.type,inImage.depth,inImage.data);
}

inline void fromXVImage_Link(XVImage& inImage,xvs::Image& outImage)
{
//    outImage = Image(inImage.width,inImage.height,(ImageData::PlainType)inImage.type,inImage.depth,inImage.data);
}




////***************************************************************************
////***************************************************************************
////***************************************************************************
//inline void fromXVRobotFlangePose(RobotFlangePose& inValue,xvs::FlangePose& outValue)
//{
//    outValue.setX(inValue.x);
//    outValue.setY(inValue.y);
//    outValue.setZ(inValue.z);

//    outValue.setU(inValue.U);
//    outValue.setV(inValue.V);
//    outValue.setW(inValue.W);

//    outValue.setJ1(inValue.J1);
//    outValue.setJ2(inValue.J2);
//    outValue.setJ3(inValue.J3);
//    outValue.setJ4(inValue.J4);
//}

//inline void toXVRobotFlangePose(xvs::FlangePose& inValue,RobotFlangePose& outValue)
//{
//    outValue.x = inValue.X();
//    outValue.y = inValue.Y();
//    outValue.z = inValue.Z();

//    outValue.U = inValue.U();
//    outValue.V = inValue.V();
//    outValue.W = inValue.W();

//    outValue.J1 = inValue.J1();
//    outValue.J2 = inValue.J2();
//    outValue.J3 = inValue.J3();
//    outValue.J4 = inValue.J4();
//}



//***************************************************************************
//***************************************************************************
//***************************************************************************


}

#endif // CVT_XVL_H
